/**
 * Copyright Statement:
 * This software and related documentation (ESWIN SOFTWARE) are protected under relevant copyright laws.
 * The information contained herein is confidential and proprietary to
 * Beijing ESWIN Computing Technology Co., Ltd.(ESWIN)and/or its licensors.
 * Without the prior written permission of ESWIN and/or its licensors, any reproduction, modification,
 * use or disclosure Software, and information contained herein, in whole or in part, shall be strictly prohibited.
 *
 * Copyright ©[2023] [Beijing ESWIN Computing Technology Co., Ltd.]. All rights reserved.
 *
 * RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES THAT THE SOFTWARE
 * AND ITS DOCUMENTATIONS (ESWIN SOFTWARE) RECEIVED FROM ESWIN AND / OR ITS REPRESENTATIVES
 * ARE PROVIDED TO RECEIVER ON AN "AS-IS" BASIS ONLY. ESWIN EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE OR NON INFRINGEMENT.
 * NEITHER DOES ESWIN PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY
 * WHICH MAY BE USED BY,INCORPORATED IN, OR SUPPLIED WITH THE ESWIN SOFTWARE,
 * AND RECEIVER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL ESWIN BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 * @file main.c
 * @brief 传感器监控系统主程序 - 基于FreeRTOS
 * @author abu (abu@eswincomputing.com)
 * @date 2024-01-24
 *
 * @details
 * 传感器监控系统功能：
 * 1. 数据采集：DHT11温湿度、LED状态、PWM输出、蜂鸣器状态
 * 2. 数据存储：SD卡存储传感器数据
 * 3. 数据显示：LCD屏幕实时显示
 * 4. 蓝牙通信：手机远程控制和查询
 * 5. 多任务并发：FreeRTOS任务管理
 *
 * @platform ESWIN EAM2011 Fullmask evb board
 *
 * Modification History :
 * Date:               Version:                    Author:
 * Changes:
 *
 */

#include "../board/sdk_project_config.h"
#include "arduino.h"
#include "spi_sd_driver.h"
#include "lcd.h"
// 添加SD卡寄存器头文件，包含SD_SUCCESS常量定义
#include "../ESWIN_SDK/drivers/src/spi_sd/sd_register.h"
// 添加log头文件，用于printf端口配置
#include "../ESWIN_SDK/log/include/log.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// ==================== 系统配置 ====================
#define SENSOR_SAMPLE_PERIOD_MS    2000    // 传感器采样周期(ms)
#define DISPLAY_UPDATE_PERIOD_MS   1000    // 显示更新周期(ms)
#define SD_WRITE_PERIOD_MS         5000    // SD卡写入周期(ms)
#define BLUETOOTH_BUFFER_SIZE      256     // 蓝牙接收缓冲区大小

// ==================== 任务优先级 ====================
#define TASK_PRIORITY_SENSOR       5       // 传感器采集任务优先级
#define TASK_PRIORITY_DISPLAY      4       // 显示任务优先级
#define TASK_PRIORITY_STORAGE      3       // 存储任务优先级
#define TASK_PRIORITY_BLUETOOTH    6       // 蓝牙通信任务优先级
#define TASK_PRIORITY_CONTROL      2       // 控制任务优先级

// ==================== 任务堆栈大小 ====================
#define TASK_STACK_SIZE_SENSOR     1024    // 传感器任务堆栈
#define TASK_STACK_SIZE_DISPLAY    1024    // 显示任务堆栈
#define TASK_STACK_SIZE_STORAGE    1024    // 存储任务堆栈
#define TASK_STACK_SIZE_BLUETOOTH  1024    // 蓝牙任务堆栈
#define TASK_STACK_SIZE_CONTROL    512     // 控制任务堆栈

// ==================== 超时常量定义 ====================
#define OS_WAIT_FOREVER            0xFFFFFFFF  // 永久等待超时值

// ==================== 全局变量 ====================
// 传感器数据结构
typedef struct {
    uint8_t temperature_int;       // 温度整数部分
    uint8_t temperature_dec;       // 温度小数部分
    uint8_t humidity_int;          // 湿度整数部分
    uint8_t humidity_dec;          // 湿度小数部分
    uint8_t led_status;            // LED状态
    uint8_t buzzer_status;         // 蜂鸣器状态
    uint16_t pwm_value;            // PWM值
    uint32_t timestamp;            // 时间戳
} sensor_data_t;

// 系统状态
typedef struct {
    uint8_t system_ready;          // 系统就绪标志
    uint8_t sd_card_ready;         // SD卡就绪标志
    uint8_t bluetooth_connected;   // 蓝牙连接状态
    uint8_t sensor_error;          // 传感器错误标志
} system_status_t;

// DHT11数据结构
typedef struct {
    uint8_t temp_int;
    uint8_t temp_dec;
    uint8_t hum_int;
    uint8_t hum_dec;
} DHT11_Data_t;

// 声明DHT11.c中的外部变量
extern int temp_int;
extern int temp_dec;
extern int hum_int;
extern int hum_dec;

// 全局变量
static sensor_data_t g_sensor_data = {0};
static system_status_t g_system_status = {0};
static uint8_t g_bluetooth_rx_buffer[BLUETOOTH_BUFFER_SIZE];
static uint8_t g_bluetooth_rx_index = 0;

// ==================== FreeRTOS对象 ====================
static OS_ThreadId_t g_sensor_task_id = NULL;
static OS_ThreadId_t g_display_task_id = NULL;
static OS_ThreadId_t g_storage_task_id = NULL;
static OS_ThreadId_t g_bluetooth_task_id = NULL;
static OS_ThreadId_t g_control_task_id = NULL;

static OS_MessageQueueId_t g_sensor_queue_id = NULL;
static OS_MessageQueueId_t g_command_queue_id = NULL;
static OS_MutexId_t g_sensor_mutex_id = NULL;
static OS_MutexId_t g_display_mutex_id = NULL;

// ==================== 函数声明 ====================
static void SensorTask(void *argument);
static void DisplayTask(void *argument);
static void StorageTask(void *argument);
static void BluetoothTask(void *argument);
static void ControlTask(void *argument);

static void SensorSystemInit(void);  // 重命名避免与系统函数冲突
static void HardwareInit(void);
static void TaskInit(void);
static void ReadDHT11Data(void);
static void ProcessBluetoothCommand(const char *command);
static void SendBluetoothResponse(const char *response);
static void UpdateLCDDisplay(void);
static void WriteDataToSD(void);
static void MotorControl(uint8_t action);

// ==================== 系统初始化 ====================
static void SensorSystemInit(void)
{
    printf("=== 传感器监控系统启动 ===\r\n");
    
    // 初始化时钟
    CLOCK_SYS_Init(g_pstClockManConfigsArr[0]);
    printf("时钟初始化完成\r\n");
    
    // 初始化引脚
    PINS_DRV_Init(NUM_OF_CONFIGURED_PINS, g_stPinmuxConfigArr);
    printf("引脚初始化完成\r\n");
    
    // 初始化硬件
    HardwareInit();
    
    // 初始化任务
    TaskInit();
    
    printf("系统初始化完成\r\n");
}

static void HardwareInit(void)
{
    // 初始化UART1 (蓝牙HC05)
    UART_DRV_Init(INST_UART_1, &g_stUartState_1, &g_stUart1UserConfig0);
    printf("UART1(蓝牙)初始化完成\r\n");
    
    // 初始化UART2 (调试终端)
    UART_DRV_Init(INST_UART_2, &g_stUartState_2, &g_stUart2UserConfig0);
    printf("UART2(调试终端)初始化完成\r\n");
    
    // 配置printf输出端口为UART2
    setLogPort(INST_UART_2);
    printf("printf输出端口配置为UART2\r\n");
    
    // 初始化SPI0 (SD卡)
    if (SD_DRV_Init(INST_SPI_0) == SD_SUCCESS) {
        g_system_status.sd_card_ready = 1;
        printf("SD卡初始化成功\r\n");
    } else {
        g_system_status.sd_card_ready = 0;
        printf("SD卡初始化失败\r\n");
    }
    
    // 初始化PWM1
    PWM_DRV_Init(INST_PWM_1, &g_stPwmState_1, &g_stPwm1Config0);
    printf("PWM1初始化完成\r\n");
    
    // 初始化LCD (这里需要根据实际LCD驱动进行调用)
    // LCD_Init();
    printf("LCD初始化完成\r\n");
    
    g_system_status.system_ready = 1;
}

static void TaskInit(void)
{
    // 创建消息队列
    g_sensor_queue_id = OS_MessageQueueNew(10, sizeof(sensor_data_t), NULL);
    g_command_queue_id = OS_MessageQueueNew(5, 64, NULL);
    
    // 创建互斥锁
    g_sensor_mutex_id = OS_MutexNew(NULL);
    g_display_mutex_id = OS_MutexNew(NULL);
    
    // 创建任务
    g_sensor_task_id = OS_ThreadNew(SensorTask, NULL, NULL);
    g_display_task_id = OS_ThreadNew(DisplayTask, NULL, NULL);
    g_storage_task_id = OS_ThreadNew(StorageTask, NULL, NULL);
    g_bluetooth_task_id = OS_ThreadNew(BluetoothTask, NULL, NULL);
    g_control_task_id = OS_ThreadNew(ControlTask, NULL, NULL);
    
    printf("FreeRTOS任务创建完成\r\n");
}

// ==================== 传感器数据采集任务 ====================
static void SensorTask(void *argument)
{
    sensor_data_t sensor_data;
    uint32_t last_sample_time = 0;
    
    printf("传感器采集任务启动\r\n");
    
    while (1) {
        uint32_t current_time = OS_KernelGetTickCount();
        
        // 定时采集传感器数据
        if (current_time - last_sample_time >= OS_Msec2Tick(SENSOR_SAMPLE_PERIOD_MS)) {
            // 读取DHT11温湿度数据
            ReadDHT11Data();
            
            // 获取当前传感器数据
            OS_MutexAcquire(g_sensor_mutex_id, OS_WAIT_FOREVER);
            sensor_data = g_sensor_data;
            OS_MutexRelease(g_sensor_mutex_id);
            
            // 添加时间戳
            sensor_data.timestamp = current_time;
            
            // 发送数据到消息队列
            if (g_sensor_queue_id != NULL) {
                OS_MessageQueuePut(g_sensor_queue_id, &sensor_data, 0, 0);
            }
            
            last_sample_time = current_time;
            printf("传感器数据采集完成: T=%d.%d°C, H=%d.%d%%\r\n", 
                   sensor_data.temperature_int, sensor_data.temperature_dec,
                   sensor_data.humidity_int, sensor_data.humidity_dec);
        }
        
        OS_DelayMs(100);
    }
}

static void ReadDHT11Data(void)
{
    // 调用Arduino DHT11函数读取数据
    Arduino_Dht11_Example();
    
    // 更新全局传感器数据
    OS_MutexAcquire(g_sensor_mutex_id, OS_WAIT_FOREVER);
    g_sensor_data.temperature_int = temp_int;
    g_sensor_data.temperature_dec = temp_dec;
    g_sensor_data.humidity_int = hum_int;
    g_sensor_data.humidity_dec = hum_dec;
    OS_MutexRelease(g_sensor_mutex_id);
}

// ==================== 显示任务 ====================
static void DisplayTask(void *argument)
{
    uint32_t last_update_time = 0;
    
    printf("显示任务启动\r\n");
    
    while (1) {
        uint32_t current_time = OS_KernelGetTickCount();
        
        // 定时更新显示
        if (current_time - last_update_time >= OS_Msec2Tick(DISPLAY_UPDATE_PERIOD_MS)) {
            UpdateLCDDisplay();
            last_update_time = current_time;
        }
        
        OS_DelayMs(100);
    }
}

static void UpdateLCDDisplay(void)
{
    char display_buffer[128];
    sensor_data_t sensor_data;
    
    // 获取传感器数据
    OS_MutexAcquire(g_sensor_mutex_id, OS_WAIT_FOREVER);
    sensor_data = g_sensor_data;
    OS_MutexRelease(g_sensor_mutex_id);
    
    // 格式化显示字符串
    snprintf(display_buffer, sizeof(display_buffer), 
             "Sensor Monitor System\r\n"
             "Temp: %d.%d°C\r\n"
             "Humi: %d.%d%%\r\n"
             "LED: %s\r\n"
             "PWM: %d\r\n"
             "BT: %s\r\n"
             "SD: %s",
             sensor_data.temperature_int, sensor_data.temperature_dec,
             sensor_data.humidity_int, sensor_data.humidity_dec,
             sensor_data.led_status ? "ON" : "OFF",
             sensor_data.pwm_value,
             g_system_status.bluetooth_connected ? "Connected" : "Disconnected",
             g_system_status.sd_card_ready ? "Ready" : "Error");
    
    // 更新LCD显示 (需要根据实际LCD驱动进行调用)
    // LCD_Clear();
    // LCD_ShowString(0, 0, display_buffer);
    
    printf("LCD显示更新: %s\r\n", display_buffer);
}

// ==================== 存储任务 ====================
static void StorageTask(void *argument)
{
    sensor_data_t sensor_data;
    uint32_t last_write_time = 0;
    uint32_t sd_write_addr = 0;
    
    printf("存储任务启动\r\n");
    
    while (1) {
        uint32_t current_time = OS_KernelGetTickCount();
        
        // 定时写入SD卡
        if (current_time - last_write_time >= OS_Msec2Tick(SD_WRITE_PERIOD_MS)) {
            if (g_system_status.sd_card_ready) {
                WriteDataToSD();
                last_write_time = current_time;
            }
        }
        
        OS_DelayMs(100);
    }
}

static void WriteDataToSD(void)
{
    sensor_data_t sensor_data;
    char data_buffer[128];
    uint8_t write_buffer[512];
    
    // 获取传感器数据
    OS_MutexAcquire(g_sensor_mutex_id, OS_WAIT_FOREVER);
    sensor_data = g_sensor_data;
    OS_MutexRelease(g_sensor_mutex_id);
    
    // 格式化数据字符串
    snprintf(data_buffer, sizeof(data_buffer),
             "%lu,%d.%d,%d.%d,%d,%d,%d\r\n",
             sensor_data.timestamp,
             sensor_data.temperature_int, sensor_data.temperature_dec,
             sensor_data.humidity_int, sensor_data.humidity_dec,
             sensor_data.led_status, sensor_data.buzzer_status, sensor_data.pwm_value);
    
    // 填充512字节缓冲区
    memset(write_buffer, 0, sizeof(write_buffer));
    strncpy((char*)write_buffer, data_buffer, sizeof(write_buffer) - 1);
    
    // 写入SD卡
    static uint32_t sd_sector = 0;
    if (SD_DRV_WriteDisk(INST_SPI_0, write_buffer, sd_sector, 1) == SD_SUCCESS) {
        sd_sector++;
        printf("SD卡写入成功: 扇区%d\r\n", sd_sector);
    } else {
        printf("SD卡写入失败\r\n");
    }
}

// ==================== 蓝牙通信任务 ====================
static void BluetoothTask(void *argument)
{
    uint8_t rx_byte;
    uint32_t bytes_remaining;
    
    printf("蓝牙通信任务启动\r\n");
    
    // 发送欢迎消息
    const char *welcome_msg = "Sensor Monitor System Ready\r\n";
    UART_DRV_SendDataBlocking(INST_UART_1, (uint8_t*)welcome_msg, strlen(welcome_msg), 1000);
    
    while (1) {
        // 接收蓝牙数据
        UART_DRV_ReceiveData(INST_UART_1, &rx_byte, 1);
        
        // 等待接收完成
        while (UART_DRV_GetReceiveStatus(INST_UART_1, &bytes_remaining) == STATUS_BUSY) {
            OS_DelayMs(1);
        }
        
        if (UART_DRV_GetReceiveStatus(INST_UART_1, &bytes_remaining) == STATUS_SUCCESS) {
            // 处理接收到的字节
            if (rx_byte == '\r' || rx_byte == '\n') {
                if (g_bluetooth_rx_index > 0) {
                    g_bluetooth_rx_buffer[g_bluetooth_rx_index] = '\0';
                    ProcessBluetoothCommand((char*)g_bluetooth_rx_buffer);
                    g_bluetooth_rx_index = 0;
                }
            } else if (g_bluetooth_rx_index < BLUETOOTH_BUFFER_SIZE - 1) {
                g_bluetooth_rx_buffer[g_bluetooth_rx_index++] = rx_byte;
            }
        }
        
        OS_DelayMs(10);
    }
}

static void ProcessBluetoothCommand(const char *command)
{
    printf("收到蓝牙命令: %s\r\n", command);
    
    if (strncmp(command, "GET_TEMP", 8) == 0) {
        // 查询温度
        char response[64];
        snprintf(response, sizeof(response), "Temperature: %d.%d°C\r\n", 
                g_sensor_data.temperature_int, g_sensor_data.temperature_dec);
        SendBluetoothResponse(response);
    }
    else if (strncmp(command, "GET_HUMI", 8) == 0) {
        // 查询湿度
        char response[64];
        snprintf(response, sizeof(response), "Humidity: %d.%d%%\r\n", 
                g_sensor_data.humidity_int, g_sensor_data.humidity_dec);
        SendBluetoothResponse(response);
    }
    else if (strncmp(command, "GET_ALL", 7) == 0) {
        // 查询所有数据
        char response[128];
        snprintf(response, sizeof(response), 
                "Temp:%d.%d°C,Humi:%d.%d%%,LED:%d,PWM:%d\r\n",
                g_sensor_data.temperature_int, g_sensor_data.temperature_dec,
                g_sensor_data.humidity_int, g_sensor_data.humidity_dec,
                g_sensor_data.led_status, g_sensor_data.pwm_value);
        SendBluetoothResponse(response);
    }
    else if (strncmp(command, "LED_ON", 6) == 0) {
        // 打开LED
        PINS_DRV_WritePin(PORTC, 4, 1);
        g_sensor_data.led_status = 1;
        SendBluetoothResponse("LED turned ON\r\n");
    }
    else if (strncmp(command, "LED_OFF", 7) == 0) {
        // 关闭LED
        PINS_DRV_WritePin(PORTC, 4, 0);
        g_sensor_data.led_status = 0;
        SendBluetoothResponse("LED turned OFF\r\n");
    }
    else if (strncmp(command, "BUZZER_ON", 9) == 0) {
        // 打开蜂鸣器
        PINS_DRV_WritePin(PORTB, 30, 1);
        g_sensor_data.buzzer_status = 1;
        SendBluetoothResponse("Buzzer turned ON\r\n");
    }
    else if (strncmp(command, "BUZZER_OFF", 10) == 0) {
        // 关闭蜂鸣器
        PINS_DRV_WritePin(PORTB, 30, 0);
        g_sensor_data.buzzer_status = 0;
        SendBluetoothResponse("Buzzer turned OFF\r\n");
    }
    else if (strncmp(command, "PWM_", 4) == 0) {
        // 设置PWM值
        int pwm_value = atoi(command + 4);
        if (pwm_value >= 0 && pwm_value <= 100) {
            // 这里需要根据实际PWM驱动进行设置
            // PWM_DRV_SetDutyCycle(INST_PWM_1, pwm_value);
            g_sensor_data.pwm_value = pwm_value;
            char response[64];
            snprintf(response, sizeof(response), "PWM set to %d%%\r\n", pwm_value);
            SendBluetoothResponse(response);
        } else {
            SendBluetoothResponse("Invalid PWM value (0-100)\r\n");
        }
    }
    else if (strncmp(command, "MOTOR_", 6) == 0) {
        // 电机控制命令
        if (strcmp(command + 6, "FORWARD") == 0) {
            MotorControl(1);
            SendBluetoothResponse("Motor forward\r\n");
        }
        else if (strcmp(command + 6, "BACKWARD") == 0) {
            MotorControl(2);
            SendBluetoothResponse("Motor backward\r\n");
        }
        else if (strcmp(command + 6, "STOP") == 0) {
            MotorControl(0);
            SendBluetoothResponse("Motor stop\r\n");
        }
        else {
            SendBluetoothResponse("Invalid motor command\r\n");
        }
    }
    else if (strcmp(command, "HELP") == 0) {
        // 帮助信息
        const char *help_msg = "Available commands:\r\n"
                              "GET_TEMP - Get temperature\r\n"
                              "GET_HUMI - Get humidity\r\n"
                              "GET_ALL - Get all sensor data\r\n"
                              "LED_ON/OFF - Control LED\r\n"
                              "BUZZER_ON/OFF - Control buzzer\r\n"
                              "PWM_0-100 - Set PWM value\r\n"
                              "MOTOR_FORWARD/BACKWARD/STOP - Control motor\r\n"
                              "HELP - Show this help\r\n";
        SendBluetoothResponse(help_msg);
    }
    else {
        SendBluetoothResponse("Unknown command. Type HELP for available commands.\r\n");
    }
}

static void SendBluetoothResponse(const char *response)
{
    UART_DRV_SendDataBlocking(INST_UART_1, (uint8_t*)response, strlen(response), 1000);
}

// ==================== 控制任务 ====================
static void ControlTask(void *argument)
{
    printf("控制任务启动\r\n");
    
    while (1) {
        // 这里可以添加一些系统级的控制逻辑
        // 比如系统状态监控、错误处理等
        
        OS_DelayMs(1000);
    }
}

static void MotorControl(uint8_t action)
{
    // 电机控制函数 - 预留接口
    // 这里可以根据实际硬件进行电机控制
    switch (action) {
        case 0: // 停止
            printf("电机停止\r\n");
            break;
        case 1: // 前进
            printf("电机前进\r\n");
            break;
        case 2: // 后退
            printf("电机后退\r\n");
            break;
        default:
            printf("无效的电机控制命令\r\n");
            break;
    }
}

// ==================== 主函数 ====================
int main(void)
{
    // 系统初始化
    SensorSystemInit();
    
    // 启动FreeRTOS调度器
    OS_KernelStart();
    
    // 正常情况下不会执行到这里
    while (1) {
        OS_DelayMs(1000);
    }
    
    return 0;
}
